package org.redrock.test.controller;

import com.google.gson.Gson;
import lombok.Data;
import org.redrock.test.bean.*;
import org.redrock.test.config.WeixinConfig;
import org.redrock.test.controller.command.LoginCommand;
import org.redrock.test.controller.command.WeixinConfigCommand;
import org.redrock.test.exception.WeixinException;
import org.redrock.test.interceptor.annotation.Auth;
import org.redrock.test.interceptor.impl.JwtAuth;
import org.redrock.test.repository.JwtRepository;
import org.redrock.test.repository.NetworkRepository;
import org.redrock.test.repository.UserInfoRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.json.GsonJsonParser;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.swing.*;
import javax.validation.Valid;
import java.util.Map;
import static org.apache.commons.codec.digest.DigestUtils.md5Hex;
import static org.apache.commons.codec.digest.DigestUtils.sha1Hex;

@Controller
@RequestMapping(value = "/api", headers = "version=1.0")
@EnableConfigurationProperties({WeixinConfig.class})
public class ApiControllerV1 {
    private final Logger logger = LoggerFactory.getLogger(ApiControllerV1.class);

    @Autowired
    private NetworkRepository networkRepository;
    @Autowired
    private WeixinConfig weixinConfig;
    @Autowired
    private JwtRepository jwtRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;

    @Data
    static class Error {
        private String msg;
        public Error(String msg) {
            this.msg = msg;
        }
    }

    @GetMapping("/weixinConfig")
    public ResponseEntity<Object> getWeixinConfig(@Valid WeixinConfigCommand weixinConfigCommand, BindingResult result) {
        if (!result.hasErrors()) {
            String timestamp = weixinConfigCommand.getTimestamp();
            String nonce = weixinConfigCommand.getNonce();
            String secret = weixinConfigCommand.getSecret();
            String signature = sha1Hex(sha1Hex(timestamp) + md5Hex(nonce) + "redrock");
            if (signature.equalsIgnoreCase(secret)) {
                return new ResponseEntity<>(
                        weixinConfig.clone(),
                        HttpStatus.OK
                );
            }
        }
        return new ResponseEntity<>(
                new Error("参数有误"),
                HttpStatus.BAD_REQUEST
        );
    }

    @GetMapping("/token/{code}")
    public ResponseEntity<Object> webAuth1(@PathVariable String code) {
        if (!StringUtils.isEmpty(code)) {
            String appId = weixinConfig.getAppId();
            String wSecret = weixinConfig.getSecret();
            String getUserAccessTokenApi = String.format(
                    "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                    appId,
                    wSecret,
                    code
            );
            RequestInfo requestInfo = new RequestInfo("get", getUserAccessTokenApi);
            String data = networkRepository.curl(requestInfo);
            GsonJsonParser parser = new GsonJsonParser();
            Map parseData = parser.parseMap(data);
            if (StringUtils.isEmpty(parseData.get("errmsg"))) {
                UserAccessToken userAccessToken = new Gson().fromJson(data, UserAccessToken.class);
                if (!StringUtils.isEmpty(userAccessToken.getAccess_token())) {
                    JsonWebToken jwt = jwtRepository.getJwtByUserAccessToken(userAccessToken);
                    return new ResponseEntity<>(jwt, HttpStatus.OK);
                }
            }
        }
        return new ResponseEntity<>(new Error("code 无效"), HttpStatus.BAD_REQUEST);
    }

    @GetMapping("/userInfo/{token}")
    public ResponseEntity<Object> userInfo1(@PathVariable String token) {
        try {
            if (!StringUtils.isEmpty(token)) {
                String openId = jwtRepository.getOpenIdByToken(token);
                UserInfo userInfo = userInfoRepository.getUserInfo(openId);
                return new ResponseEntity<>(userInfo, HttpStatus.OK);
            }
        } catch (WeixinException e) {
            logger.debug("通过accessToken获取用户信息出错", token ,e);
            return new ResponseEntity<>(new Error(e.getErrorMsg()), e.getHttpStatus());
        }
        return new ResponseEntity<>(new Error("token 不可为空"), HttpStatus.BAD_REQUEST);
    }

    @Auth(JwtAuth.class)
    @PutMapping("/login")
    public void refresh1(JwtFormData jwtFormData) {
        try {
            LoginCommand loginCommand = jwtRepository.parseToObject(jwtFormData, LoginCommand.class);
            System.out.println(loginCommand.toString());
        } catch (WeixinException e) {
            e.printStackTrace();
        }

    }

}
